<?php



/**
 * Radcodes - SocialEngine Module
 *
 * @category   Application_Extensions
 * @package    Game
 * @copyright  Copyright (c) 2009-2010 Radcodes LLC (http://www.radcodes.com)
 * @license    http://www.radcodes.com/license/
 * @version    $Id$
 * @author     Vincent Van <vincent@radcodes.com>
 */
 
 
 
class Game_Api_Core extends Core_Api_Abstract
{
  const IMAGE_WIDTH = 720;
  const IMAGE_HEIGHT = 720;

  const THUMB_WIDTH = 140;
  const THUMB_HEIGHT = 160;
  
  protected $_types;
  

  /**
   * @return null | false | true
   */
  public function checkCrossDomainXml()
  {
    $filename = APPLICATION_PATH . DS . 'crossdomain.xml'; 
    
    if (!file_exists($filename)) {
      return null;
    }
    
    $content = file_get_contents($filename);
    return (strpos($content, 'mochiads.com') !== false);
  }
  
  
  public function getCategoryOptions($params = array())
  {
    return $this->convertCategoriesToArray($this->getCategories($params));
  }  
  
  public function getCategories($params = array())
  {
    $table = Engine_Api::_()->getDbtable('categories', 'game');
    $categories = $table->fetchAll($table->select()->order('order'));
    
    return $categories;
  }
  
  public function getCategory($category_id)
  {
    return Engine_Api::_()->getItemTable('game_category')->getCategory($category_id);
  }
  


  public function getGame($game_id)
  {
    static $games = array();
    
    if (!isset($games[$game_id]))
    {
      $games[$game_id] = Engine_Api::_()->getDbtable('games', 'game')->find($game_id)->current();
    }
    
    return $games[$game_id];
  } 
  
  public function convertCategoriesToArray($categories)
  {
    return $this->convertItemsToArray($categories);
  }
  
  public function convertItemsToArray($items)
  {
    $data = array();
    foreach ($items as $item) {
      $data[$item->getIdentity()] = $item->getTitle();
    }
    return $data;
  }
  
  public function countGames($params = array())
  {
    $paginator = $this->getGamesPaginator($params);
    return $paginator->getTotalItemCount();  
  }
  
  // Select
  /**
   * Gets a paginator for games
   *
   * @param Core_Model_Item_Abstract $user The user to get the messages for
   * @return Zend_Paginator
   */
  public function getGamesPaginator($params = array(), $options = null)
  {
    $paginator = Zend_Paginator::factory($this->getGamesSelect($params, $options));
    if( !empty($params['page']) )
    {
      $paginator->setCurrentPageNumber($params['page']);
    }
    if( !empty($params['limit']) )
    {
      $paginator->setItemCountPerPage($params['limit']);
    }
    return $paginator;
  }

  /**
   * Gets a select object for the user's game entries
   *
   * @param Core_Model_Item_Abstract $user The user to get the messages for
   * @return Zend_Db_Table_Select
   */
  public function getGamesSelect($params = array(), $options = null)
  {
    $table = $this->getGameTable();
    
    $rName = $table->info('name');

    if (empty($params['order'])) {
      $params['order'] = 'recent';
    }    
    
    $select = $table->selectParamBuilder($params);
    
    // Process options
    $tmp = array();
    foreach( $params as $k => $v ) {
      if( null == $v || '' == $v || (is_array($v) && count(array_filter($v)) == 0) ) {
        continue;
      } else if( false !== strpos($k, '_field_') ) {
        list($null, $field) = explode('_field_', $k);
        $tmp['field_' . $field] = $v;
      } else if( false !== strpos($k, '_alias_') ) {
        list($null, $alias) = explode('_alias_', $k);
        $tmp[$alias] = $v;
      } else {
        $tmp[$k] = $v;
      }
    }
    $params = $tmp;     
    
    // Build search part of query
    $searchParts = Engine_Api::_()->fields()->getSearchQuery('game', $params);
    if (!empty($searchParts))
    {
      $searchTable = Engine_Api::_()->fields()->getTable('game', 'search')->info('name');
      
      $select = $select
        ->setIntegrityCheck(false)
        ->from($rName)
        ->joinLeft($searchTable, "$searchTable.item_id = $rName.game_id")
        ->group("$rName.game_id");     
      foreach( $searchParts as $k => $v ) 
      {
        $select = $select->where("`{$searchTable}`.{$k}", $v);
      }
    }      
    
    if( !empty($params['tag']) )
    {          
      $tagTable = Engine_Api::_()->getDbtable('TagMaps', 'core')->info('name');
      
      $select = $select
        ->setIntegrityCheck(false)
        ->from($rName)
        ->joinLeft($tagTable, "$tagTable.resource_id = $rName.game_id")
        ->where($tagTable.'.resource_type = ?', 'game')
        ->where($tagTable.'.tag_id  IN (?)', $params['tag']);
        if (is_array($params['tag'])) {
          $select->group("$rName.game_id");
        }
    }

    if (!empty($params['favorite_user_id']))
    {
      $favoriteTable = Engine_Api::_()->getItemTable('game_favorite');
      $favoriteTableName = $favoriteTable->info('name');
      $subselect = new Zend_Db_Select($favoriteTable->getAdapter());
      $subselect->from($favoriteTableName, array('game_id'))
        ->where($favoriteTableName.".user_id = ?", $params['favorite_user_id']);
      
      $select->where($rName.".game_id IN (".$subselect->__toString().")");
    }
   
    //echo $select->__toString();
    //exit;
    return $select;
  }

  
  public function filterEmptyParams($values)
  {
    foreach ($values as $key => $value)
    {
      if (is_array($value))
      {
        foreach ($value as $value_k => $value_v)
        {
          if (!strlen($value_v))
          {
            unset($value[$value_k]);
          }
        }
      }
      
      if (is_array($value) && count($value) == 0)
      {
        unset($values[$key]);
      }
      else if (!is_array($value) && !strlen($value))
      {
        unset($values[$key]);
      }
    }
    
    return $values;
  }
  
  public function getPopularTags($options = array())
  {
    $resource_type = 'game';
    
    $tag_table = Engine_Api::_()->getDbtable('tags', 'core');
    $tagmap_table = $tag_table->getMapTable();
    
    $tName = $tag_table->info('name');
    $tmName = $tagmap_table->info('name');
    
    if (isset($options['order']))
    {
      $order = $options['order'];
    }
    else
    {
      $order = 'text';
    }
    
    if (isset($options['sort']))
    {
      $sort = $options['sort'];
    }
    else
    {
      $sort = $order == 'total' ? SORT_DESC : SORT_ASC;
    }
    
    $limit = isset($options['limit']) ? $options['limit'] : 50;
    
    $select = $tag_table->select()
        ->setIntegrityCheck(false)
        ->from($tmName, array('total' => "COUNT(*)"))
        ->join($tName, "$tName.tag_id = $tmName.tag_id")
        ->where($tmName.'.resource_type = ?', $resource_type)
        ->where($tmName.'.tag_type = ?', 'core_tag')
        ->group("$tName.tag_id")
        ->order("total desc")
        ->limit("$limit");

    $params = array('live' => true); 
    $game_table = $this->getGameTable();
    $rName = $game_table->info('name');
    
            
    
    $select->setIntegrityCheck(false)
        ->join($rName, "$tmName.resource_id = $rName.game_id");
    $select = $game_table->selectParamBuilder($params, $select);    
    //echo $select;
    
    $tags = $tag_table->fetchAll($select);   
    
    $records = array();
    
    $columns = array();
    if (!empty($tags))
    {
      foreach ($tags as $k => $tag)
      {
        $records[$k] = $tag;
        $columns[$k] = $order == 'total' ? $tag->total : $tag->text; 
      }
    }

    $tags = array();
    if (count($columns))
    {
      if ($order == 'text') {
        natcasesort($columns);
      }
      else {
        arsort($columns);
      }

      foreach ($columns as $k => $name)
      {
        $tags[$k] = $records[$k];
      }
    }

    return $tags;
  }  
  
  public function getRelatedGames($game, $params = array())
  {
    // related games
    $tag_ids = array();
    foreach ($game->tags()->getTagMaps() as $tagMap) {
      $tag = $tagMap->getTag();
      if (!empty($tag->text)) {
        $tag_ids[] = $tag->tag_id;
      }
    }
    //print_r($tag_ids);
    
    if (empty($tag_ids)) {
      return null;
    }
    
    $values = array(
      'tag' => $tag_ids,
      'order' => 'random',
      'limit' => 5,
      'exclude_game_ids' => array($game->getIdentity())
    );

    $params = array_merge($values, $params);
    
    $paginator = Engine_Api::_()->game()->getGamesPaginator($params);
    
    if ($paginator->getTotalItemCount() == 0) {
      return null;
    }
    
    return $paginator;
  }  
  
  
  public function getTopSubmitters($params = array())
  {
    $column = 'user_id';
    
    $table = $this->getGameTable();
    $rName = $table->info('name');
    
    $select = new Zend_Db_Select($table->getAdapter());
    $select->from($table->info('name'), array(
      'user_id' => $column,
      'total' => new Zend_Db_Expr('COUNT(*)'),
    ));
    $select->group($column);

    $select->order('total desc');
    
    if (isset($params['limit'])) {
      $select->limit($params['limit']);
      unset($params['limit']);
    }
    
    $select = $table->selectParamBuilder($params, $select);
    
    $rows = $select->query()->fetchAll();
    
    $result = array();
    foreach ($rows as $row) {
      $result[$row[$column]] = $row;
    }
    
    return $result;
  }

  
  /***
   * @return Game_Model_DbTable_Games
   */
  public function getGameTable()
  {
    return Engine_Api::_()->getDbtable('games', 'game');
  }
  
  public function getSpecialAlbum(User_Model_User $user, $type = 'game')
  {
    $table = Engine_Api::_()->getDbtable('albums', 'album');

    $translate = Zend_Registry::get('Zend_Translate');
    $title = $translate->_(ucfirst($type) . ' Photos');
    
    $select = $table->select()
        ->where('owner_type = ?', $user->getType())
        ->where('owner_id = ?', $user->getIdentity())
        ->where('title = ?', $title)
        ->order('album_id ASC')
        ->limit(1);
    
    $album = $table->fetchRow($select);

    // Create wall photos album if it doesn't exist yet
    if( null === $album )
    {
      $album = $table->createRow();
      $album->owner_type = $user->getType();
      $album->owner_id = $user->getIdentity();
      $album->title = $title;
      //$album->type = $type;

      $album->search = 0;

      $album->save();
      
      // Authorizations
      $auth = Engine_Api::_()->authorization()->context;
      $auth->setAllowed($album, 'everyone', 'view',    true);
      $auth->setAllowed($album, 'everyone', 'comment', true);
        
    }

    return $album;
  }
  
  public function downloadFile($url)
  {
    // Now try to create thumbnail
    $thumbnail = (string) $url;
    $thumbnail_parsed = @parse_url($thumbnail);    
    
    $ext = $this->getFileExtensionFromUrl($url);
    
    if( $thumbnail && $thumbnail_parsed ) {
      $tmp_path = APPLICATION_PATH . '/temporary';
      $tmp_file = $tmp_path . '/' . md5($thumbnail) . '.' . $ext;
  
      if( !is_dir($tmp_path) && !mkdir($tmp_path, 0777, true) ) {
        throw new Core_Model_Exception('Unable to create tmp game folder : ' . $tmp_path);
      }

      
      $src_fh = fopen($thumbnail, 'r');
      $tmp_fh = fopen($tmp_file, 'w');
      stream_copy_to_stream($src_fh, $tmp_fh, 1024 * 1024 * 2);
      fclose($src_fh);
      fclose($tmp_fh);

      return $tmp_file;
    }
    else {
      return false;
    }
  }  
  
  public function getFileExtensionFromUrl($url)
  {
    preg_match('/[^?]*/', $url, $matches);
    $string = $matches[0];
 
    $pattern = preg_split('/\./', $string, -1, PREG_SPLIT_OFFSET_CAPTURE);

    # check if there is any extension
    if(count($pattern) == 1)
    {
      return null;
    }
   
    if(count($pattern) > 1)
    {
      $filenamepart = $pattern[count($pattern)-1][0];
      preg_match('/[^?]*/', $filenamepart, $matches);
      return $matches[0];
    } 
  }
  
  
  public function getAutoPostUrl()
  {
    $url = (constant('_ENGINE_SSL') ? 'https://' : 'http://') 
      . Zend_Controller_Front::getInstance()->getRequest()->getHttpHost();
    $url .= Zend_Controller_Front::getInstance()->getRouter()->assemble(array('controller'=>'bridge','action'=>'autopost'), 'game_extended', true);
    return $url;
  }
  
  public function getDefaultOwner()
  {
    $user_id = Engine_Api::_()->getApi('settings', 'core')->getSetting('game.userid');
    
    $owner = null;
    
    if (!empty($user_id)) {
      $owner = Engine_Api::_()->user()->getUser($user_id);
    }

    if (!($owner instanceof User_Model_User) || !$owner->getIdentity()) {
      $owner = Engine_Api::_()->user()->getViewer();
    }
    
    return $owner;
  }
  
  public function checkLicense()
  {
    $license = Engine_Api::_()->getApi('settings', 'core')->getSetting('game.license');
    return (trim($license) && $license != 'XXXX-XXXX-XXXX-XXXX');
  }
  
  
  public function convertMainCategory($categories)
  {
    $categoryMapping = Engine_Api::_()->getApi('settings', 'core')->game_categorymapping;
    
    $category_id = 0;
    foreach ($categories as $name)
    {
      $categorySettingKey = Game_Model_Category::getDistributorCategoryKey($name);
      if (!$categorySettingKey || !isset($categoryMapping[$categorySettingKey])) continue;
      $category_id = $categoryMapping[$categorySettingKey];
      if ($category_id) break;
    }   
    return $category_id;
  }
  
  public function importGame($values, $settings = array())
  {
    $viewer = Engine_Api::_()->game()->getDefaultOwner();    
    
    $category_id = null;
    if (!empty($values['categories']))
    {
      $category_id = Engine_Api::_()->game()->convertMainCategory($values['categories']);
    }
    elseif (!empty($values['category_id']))
    {
      $category_id = $values['category_id'];
    }
    
    if (!$category_id)
    {
      $values['import_result'] = 'category not match';
    }
    else
    {
      $category = Engine_Api::_()->game()->getCategory($category_id);
      if (!($category instanceof Core_Model_Item_Abstract))
      {
        $values['import_result'] = 'category not exist';
        return;
      }
      
      $values['category_id'] = $category_id;
      $values['user_id'] = $viewer->getIdentity();
      
      
      if (!isset($values['status'])) {
        $values['status'] = Game_Model_Game::STATUS_PENDING;
      }
      
      if (!isset($values['content_rating'])){
        $values['content_rating'] = Game_Model_Game::CONTENT_RATING_EVERYONE;
      }
      
      if (!isset($values['distributor_type'])) {
        $values['distributor_type'] = 'manual';
      }
      
      $table = Engine_Api::_()->getItemTable('game');
      $db = $table->getAdapter();
      $db->beginTransaction();
      
      $game = $table->createRow();
      $game->setFromArray($values);  
      $game->save();
      
      
      // Add tags
      $tags = preg_split('/[,]+/', $values['keywords']);
      $tags = array_filter(array_map("trim", $tags));
      $game->tags()->addTagMaps($viewer, $tags);
      
      if (@$settings['downloadswf']) {
        try
        {
          $values['import_download_swf'] = $game->downloadSwf();
        }
        catch (Exception $eSwf)
        {
          $values['import_download_swf'] = $eSwf;
        }
      }
      if (@$settings['downloadphoto']) {
        try
        {
          $values['import_download_photo'] = $game->downloadPhoto();
        }
        catch (Exception $ePhoto)
        {
          $values['import_download_photo'] = $ePhoto;
        }
      }
      
      // CREATE AUTH STUFF HERE
      $auth = Engine_Api::_()->authorization()->context;  
      $roles = array('owner', 'owner_member', 'owner_member_member', 'owner_network', 'registered', 'everyone');

      $auth_keys = array(
        'view' => 'everyone',
        'comment' => 'registered',
      );
      
      foreach ($auth_keys as $auth_key => $auth_default)
      {
        $auth_value = isset($values['auth_'.$auth_key]) ? $values['auth_'.$auth_key] : $auth_default;
        $authMax = array_search($auth_value, $roles);
        
        foreach( $roles as $i => $role )
        {
          $auth->setAllowed($game, $role, $auth_key, ($i <= $authMax));
        }
      }      
      
      $db->commit();
      
      $values['game_id'] = $game->getIdentity();
      $values['import_result'] = $values['game_id'];
    }
    
    return $values;
  }
  
}